<!-- 路由 -->
// 导入组件
import Vue from "vue";
import Router from "vue-router";
// 登录
import login from "@/views/login";
// 首页
import index from "@/views/index";
/**
 * 基础菜单
 */
// 虚拟人列表
import virtual from "@/views/virtual/virtual";
// 虚拟人详情
import virtualDetails from "@/views/virtualDetails/virtualDetails";
// 交互记录
import InteractionRecords from "@/views/InteractionRecords/InteractionRecords";
// 交互详情
import InteractionRecordsDetails from "@/views/InteractionRecordsDetails/InteractionRecordsDetails";
// 交互分析
import InteractionAnalysis from "@/views/InteractionAnalysis/InteractionAnalysis";
// 知识库列表
import KnowledgeList from "@/views/KnowledgeList/KnowledgeList";
// 知识库添加
import KnowledgeAdd from "@/views/KnowledgeAdd/KnowledgeAdd";
// 用户管理
import user from "@/views/system/user";
// 角色管理
import Role from "@/views/system/Role";
//  首页概览
import homePage from "@/views/charts/homePage";
// 启用路由
Vue.use(Router);
// 导出路由
export default new Router({
  routes: [
    {
      path: "/",
      name: "",
      component: login,
      hidden: true,
      meta: {
        requireAuth: false,
      },
    },
    {
      path: "/login",
      name: "登录",
      component: login,
      hidden: true,
      meta: {
        requireAuth: false,
      },
    },
    {
      path: "/index",
      name: "首页",
      component: index,
      iconCls: "el-icon-tickets",
      children: [
        {
          path: "/homePage",
          name: "首页",
          component: homePage,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/virtual/virtual",
          name: "虚拟人列表",
          component: virtual,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/virtualDetails/virtualDetails",
          name: "virtualDetails",
          component:virtualDetails,
          meta: {
            requireAuth: true,
          },
        },
        {
            path: "/InteractionRecords/InteractionRecords",
            name: "交互记录",
            component: InteractionRecords,
            meta: {
              requireAuth: true,
            },
        },
        {
            path: "/InteractionRecordsDetails/InteractionRecordsDetails",
            name: "交互详情",
            component: InteractionRecordsDetails,
            meta: {
              requireAuth: true,
            },
        },
        {
          path: "/InteractionAnalysis/InteractionAnalysis",
          name: "交互分析",
          component: InteractionAnalysis,
          meta: {
            requireAuth: true,
          },
      },
        {
            path: "/KnowledgeList/KnowledgeList",
            name: "知识库列表",
            component: KnowledgeList,
            meta: {
              requireAuth: true,
            },
        },
        {
            path: "/KnowledgeAdd/KnowledgeAdd",
            name: "保鲜效果监测",
            component: KnowledgeAdd,
            meta: {
              requireAuth: true,
            },
        },
        {
          path: "/system/user",
          name: "用户管理",
          component: user,
          meta: {
            requireAuth: true,
          },
        },
        {
          path: "/system/Role",
          name: "角色管理",
          component: Role,
          meta: {
            requireAuth: true,
          },
        },
      ],
    },
  ],
});
<!-- 左边导航菜单 -->
<template>
  <el-menu default-active="2" :collapse="collapsed" collapse-transition  router :default-active="$route.path" unique-opened class="el-menu-vertical-demo" background-color="#334157" text-color="#fff" active-text-color="#ffd04b">
    <div class="logobox">
      虚拟人交互客服系统
    </div>
    <el-submenu v-for="menu in allmenu" :key="menu.menuid" :index="menu.menuname">
      <template slot="title">
        <span>{{menu.menuname}}</span>
      </template>
      <el-menu-item-group>
        <el-menu-item v-for="chmenu in menu.menus" :index="'/'+chmenu.url" :key="chmenu.menuid">
          <span>{{chmenu.menuname}}</span>
        </el-menu-item>
      </el-menu-item-group>
    </el-submenu>
  </el-menu>
</template>
<script>
import { menu } from '../api/userMG'
export default {
  name: 'leftnav',
  data() {
    return {
      collapsed: false,
      allmenu: []
    }
  },
  created() {
    let res = {
      success: true,
      // 右侧标题
      data: [
      {
          menuid: 1,
          icon: 'li-icon-shangchengxitongtubiaozitihuayuanwenjian91',
          menuname: '首页',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 11,
              icon: 'icon-provider-manage',
              menuname: '首页',
              hasThird: 'N',
              url: 'homePage',
              menus: null
            }
          ]
        },
        {
          menuid: 2,
          icon: 'li-icon-xiangmuguanli',
          menuname: '虚拟人管理模块',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 22,
              icon: 'icon-cat-skuQuery',
              menuname: '虚拟人列表', //录入   产品详情
              hasThird: 'N',
              url: 'virtual/virtual',
              menus: null
            },
            {
              menuid: 23,
              icon: 'icon-cat-skuQuery',
              menuname: '虚拟人详情',
              hasThird: 'N',
              url: 'virtualDetails/virtualDetails',
              menus: null
            },
          ]
        },
        {
          menuid: 3,
          icon: 'li-icon-dingdanguanli',
          menuname: '交互管理模块',
          hasThird: null,
          url: null,
          menus: [
          {
              menuid: 31,
              icon: 'icon-provider-manage',
              menuname: '交互记录',
              hasThird: 'N',
              url: 'InteractionRecords/InteractionRecords',
              menus: null
            },
            {
              menuid: 32,
              icon: 'icon-order-manage',
              menuname: '交互详情',
              hasThird: 'N',
              url: 'InteractionRecordsDetails/InteractionRecordsDetails',
              menus: null
            },
            {
              menuid: 33,
              icon: 'icon-order-manage',
              menuname: '交互分析',
              hasThird: 'N',
              url: 'InteractionAnalysis/InteractionAnalysis',
              menus: null
            },
          ]
        },
        {
          menuid: 4,
          icon: 'li-icon-dingdanguanli',
          menuname: '知识库管理模块',
          hasThird: null,
          url: null,
          menus: [
          {
              menuid: 41,
              icon: 'icon-provider-manage',
              menuname: '知识库列表',
              hasThird: 'N',
              url: 'KnowledgeList/KnowledgeList',
              menus: null
            },
            {
              menuid: 42,
              icon: 'icon-provider-manage',
              menuname: '知识库添加', 
              hasThird: 'N',
              url: 'KnowledgeAdd/KnowledgeAdd',
              menus: null
            },
          ]
        },
        {
          menuid: 5,
          icon: 'li-icon-xitongguanli',
          menuname: '系统管理',
          hasThird: null,
          url: null,
          menus: [
            {
              menuid: 51,
              icon: 'icon-cus-manage',
              menuname: '用户管理',
              hasThird: 'N',
              url: 'system/user',
              menus: null
            },
            {
              menuid: 52,
              icon: 'icon-news-manage',
              menuname: '角色管理',
              hasThird: 'N',
              url: 'system/Role',
              menus: null
            },
          ]
        },
      ],
      msg: 'success'
    }
          this.allmenu = res.data
    menu(localStorage.getItem('logintoken'))
      .then(res => {
        console.log(JSON.stringify(res))
        if (res.success) {
          this.allmenu = res.data
        } else {
          this.$message.error(res.msg)
          return false
        }
      })
      .catch(err => {
        this.$message.error('数据加载失败，请稍后再试！')
      })
    // 监听
    this.$root.Bus.$on('toggle', value => {
      this.collapsed = !value
    })
  }
}
</script>
<style>
.el-menu-vertical-demo:not(.el-menu--collapse) {
  width: 240px;
  min-height: 400px;
  background-color:rgba(2, 167, 240, 1) !important;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
  border: none;
  text-align: left;
}
.el-menu-item-group__title {
  padding: 0px;
}
.el-submenu__title{
   background-color:rgba(2, 167, 240, 1) !important;
  color: white; 
}
.el-submenu__title i {
  color: white !important; 
}
.is-active{
  background-color:rgba(2, 167, 240, 1) !important;
  color: white !important;
}
.el-menu-bg {
  background-color: #1f2d3d ;
  background-color:rgba(2, 167, 240, 1) !important;
}
.el-menu-item{
  background-color:#fffff6 !important;
  color: rgba(2, 167, 240, 1) !important;
}
.el-menu {
  border: none;
}
.el-submenu{
  background-color:rgba(2, 167, 240, 1) !important;
  color: white;
}
.logobox {
  height: 40px;
  line-height: 40px;
  color: #9d9d9d;
  font-size: 20px;
  text-align: center;
  padding: 20px 0px;
  background-color:rgba(2, 167, 240, 1);
  color: white;
}
.logoimg {
  height: 40px;
}
</style>
<!-- 登录 -->
<template>
  <div class="login-wrap">
    <el-form label-position="left" :model="userForm" :loginrules="loginrules" ref="userForm" label-width="0px" class="demo-userForm login-container">
      <h3 class="title">虚拟人交互客服系统</h3>
      <el-form-item prop="username">
        <el-input type="text" v-model="userForm.username" auto-complete="off" placeholder="账号"></el-input>
      </el-form-item>
      <el-form-item prop="password">
        <el-input type="password" v-model="userForm.password" auto-complete="off" placeholder="密码"></el-input>
      </el-form-item>
      <el-row>
        <el-col :span="12">
          <el-form-item prop="code">
            <el-input type="text" v-model="userForm.code" auto-complete="off" placeholder="图形验证码" @keyup.enter.native="submitLogin('userForm')"></el-input>
          </el-form-item>
        </el-col> 
        <el-col :span="12" class="code-box">
          <img :src="userForm.codeimg" alt="" class="codeimg" @click="getcode()">
        </el-col>
      </el-row>
      <el-checkbox class="remember" v-model="rememberpwd">记住密码</el-checkbox>
      <el-form-item style="width:100%;margin:0 auto">
        <el-button type="primary" style="width:40%; margin-right: 30px;" @click="submitLogin('userForm')" :loading="logining">登录</el-button>
        <el-button style="width:40%;" @click="resetLogin">重置</el-button> 
        <el-link type="text" @click="pwReset">忘记密码？</el-link>   
      </el-form-item>
    </el-form>
    <el-dialog :visible.sync="passwordVisible" title="重置密码">
      <el-form
        :model="pwResetLogin"
        :loginrules="pwResetloginrules"
        ref="pwResetLogin"
        label-width="120px"
      >
        <el-form-item label="新密码" prop="newPassword">
          <el-input
            type="password"
            v-model="pwResetLogin.newPassword"
            placeholder="请输入新密码"
          ></el-input>
        </el-form-item>
        <el-form-item label="确认密码" prop="confirmPassword">
          <el-input
            type="password"
            v-model="pwResetLogin.confirmPassword"
            placeholder="请再次输入新密码"
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="handlepwResetSubmit"
            >提交</el-button
          >
          <el-button @click="pwResetVisible = false">取消</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>
<script type="text/ecmascript-6">
import { login } from '../api/userMG'
import { setCookie, getCookie, delCookie } from '../utils/util'
import md5 from 'js-md5'
export default {
  name: 'userlogin',
  data() {
    return {
      //定义loading默认为false
      logining: false,
      // 记住密码
      rememberpwd: false,
      userForm: {
        //username和password默认为空
        username: '',
        password: '',
        code: '',
        randomStr: '',
        codeimg: ''
      },
      //loginrules前端验证
      loginrules: {
        username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
        password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
        code: [{ required: true, message: '请输入验证码', trigger: 'blur' }]
      },
      passwordVisible: false,
      passwordForm: {
        newPassword: "",
        confirmPassword: "",
      },
      pwResetloginrules: {
        newPassword: [
          { 
            required: true,
             message: "请输入新密码",
              trigger: "blur" 
          },
          {
            min: 6,
            max: 16,
            message: "长度在 6 到 16 个字符",
            trigger: "blur",
          },
        ],
        confirmPassword: [
          { required: true, 
            message: "请再次输入新密码",
             trigger: "blur"
          },
          { 
            validator: this.validateConfirmPassword, 
            trigger: "blur" 
          },
        ],
      },
      pwResetLogin: {
        newPassword: "",
        confirmPassword: "",
      },
    }
  },
  // 创建完毕状态(里面是操作)
  created() {
    this.$message({
      message: '账号密码及验证码不为空',
      type: 'success'
    })
    // 获取图形验证码
    this.getcode()
    // 获取存在本地的用户名密码
    this.getpwd()
  },
  // 里面的函数只有调用才会执行
  methods: {
    // 获取用户名密码
    getpwd() {
      if (getCookie('user') != '' && getCookie('pwd') != '') {
        this.userForm.username = getCookie('user')
        this.userForm.password = getCookie('pwd')
        this.rememberpwd = true
      }
    },
    //获取info列表
    submitLogin(formName) {
      this.$refs[formName].validate(valid => {
        if (valid) {
          this.logining = true
          // 测试通道，不为空直接登录
          setTimeout(() => {
            this.logining = false
            this.$store.commit('login', 'true')
            this.$router.push({ path: '/surgical/surgical' })
          }, 1000)
          // 正式环境
          login(this.userForm).then(res => {
            if (res.success) {
              if (this.rememberpwd) {
                //保存帐号到cookie，有效期7天
                setCookie('user', this.userForm.username, 7)
                //保存密码到cookie，有效期7天
                setCookie('pwd', this.userForm.password, 7)
              } else {
                delCookie('user')
                delCookie('pwd')
              }
              //如果请求成功就让他2秒跳转路由
              setTimeout(() => {
                this.logining = false
                // 缓存token
                localStorage.setItem('logintoken', res.data.token)
                // 缓存用户个人信息
                localStorage.setItem('userdata', JSON.stringify(res.data))
                this.$store.commit('login', 'true')
                this.$router.push({ path: '/surgical/surgical' })
              }, 1000)
            } else {
              this.$message.error(res.msg)
              this.logining = false
              return false
            }
          })
        } else {
          // 获取图形验证码
          this.getcode()
          this.$message.error('请输入用户名密码！')
          this.logining = false
          return false
        }
      })
    },
    //密码重置
    pwReset() {
      this.passwordVisible = true;
    },
    resetLogin() {
      this.$refs.loginForm.resetFields();
    },
  }
}
</script>
<style scoped>
.login-wrap {
  box-sizing: border-box;
  width: 100%;
  height: 100%;
  padding-top: 10%;
  background-image: url('https://hbimg.huabanimg.com/54a69ab78c32221261044c8c785251ca7a9ebf102eb43-U9dV01_fw658');
  background-repeat: no-repeat;
  background-position: center right;
  background-size: 100%;
}
.login-container {
  border-radius: 10px;
  margin: 0px auto;
  width: 350px;
  padding: 30px 35px 15px 35px;
  background: #fff;
  border: 1px solid #eaeaea;
  text-align: left;
  box-shadow: 0 0 20px 2px rgba(0, 0, 0, 0.1);
}
.title {
  margin: 0px auto 40px auto;
  text-align: center;
  color: #505458;
}
.remember {
  margin: 0px 0px 35px 0px;
}
.code-box {
  text-align: right;
}
.codeimg {
  height: 40px;
}
</style>
 <!--  用户管理 -->
 <template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>用户管理</el-breadcrumb-item>
    </el-breadcrumb> 
    <el-form :inline="true" :model="uerInline" class="user-search">
      <el-form-item label="">
        <el-input size="small" v-model="uerInline.userName" placeholder="输入用户名"></el-input>
      </el-form-item>
       <el-form-item label="">
        <el-input size="small" v-model="uerInline.userMobile" placeholder="输入手机号"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="handleEdit()">添加</el-button>
      </el-form-item>
    </el-form>
    <el-table size="small" @selection-change="selectChange" :data="userData" highlight-current-row v-loading="loading" border element-loading-text="数据加载中" style="width: 100%;">
      <el-table-column align="center" type="selection" width="50">
      </el-table-column>
      <el-table-column align="center" sortable prop="userName" label="用户名" width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="userRole" label="角色" width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="userMobile" label="手机号" width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="userSex" label="性别" min-width="50">
      </el-table-column>
      <el-table-column align="center" sortable prop="userEmail" label="邮件" min-width="120">
      </el-table-column>
      <el-table-column align="center" sortable prop="editTime" label="修改时间" min-width="120">
        <template slot-scope="scope">
          <div>{{scope.row.editTime}}</div>
        </template>
      </el-table-column>
      <el-table-column align="center" sortable prop="isLock" label="状态" min-width="50">
        <template slot-scope="scope">
          <el-switch v-model="scope.row.isLock=='N'?nshow:fshow" active-color="#13ce66" inactive-color="#ff4949" @change="editType(scope.$index, scope.row)">
          </el-switch>
        </template>
      </el-table-column>
      <el-table-column align="center"  label="操作" width="300">
        <template slot-scope="scope">
          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button size="mini" type="danger" @click="deleteUser(scope.$index, scope.row)">删除</el-button>
          <el-button size="mini" type="success" @click="resetpwd(scope.$index, scope.row)">重置密码</el-button>
        </template>
      </el-table-column>
    </el-table>
    <Pagination v-bind:child-msg="pagination" @callFather="callFather"></Pagination>
    <el-dialog :title="title" :visible.sync="userFormVisible" width="30%" @click='closeDialog("edit")'>
      <el-form label-width="80px" ref="userForm" :model="userForm" :rules="rules">
        <el-form-item label="用户名" prop="userName">
          <el-input size="small" v-model="userForm.userName" auto-complete="off" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <el-form-item label="角色" prop="userRole">
          <el-input size="small" v-model="userForm.userRole" auto-complete="off" placeholder="请输入姓名"></el-input>
        </el-form-item>
        <el-form-item label="手机号" prop="userMobile">
          <el-input size="small" v-model="userForm.userMobile" placeholder="请输入手机号"></el-input>
        </el-form-item>
        <el-form-item label="邮件" prop="userEmail">
          <el-input size="small" v-model="userForm.userEmail" placeholder="请输入邮箱地址"></el-input>
        </el-form-item>
        <el-form-item label="性别" prop="userSex">
          <el-radio v-model="userForm.userSex" label="男">男</el-radio>
          <el-radio v-model="userForm.userSex" label="女">女</el-radio>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click='closeDialog("edit")'>取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="submitForm('userForm')">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  userList,
  userSave,
  userPwd,
  userLock,
} from '../../api/userMG'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      title: '添加用户',
      userFormVisible: false, //控制编辑页面显示与隐藏
      // 编辑与添加
      userForm: {
        userId: '',
        userName: '',
        userRole: '',
        roleId: '',
        userMobile: '',
        userEmail: '',
        userSex: '',
        token: localStorage.getItem('logintoken')
      },
      // 参数
      unitparm: {
        userIds: '',
        deptId: '',
        deptName: ''
      },
      // 选择数据
      selectdata: [],
      // rules表单验证
      rules: {
        userName: [
          { required: true, message: '请输入用户名', trigger: 'blur' }
        ],
        userRole: [
          { required: true, message: '请输入姓名', trigger: 'blur' }
        ],
        roleId: [{ required: true, message: '请选择角色', trigger: 'blur' }],
        userMobile: [
          { required: true, message: '请输入手机号', trigger: 'blur' },
          {
            pattern: /^1(3\d|47|5((?!4)\d)|7(0|1|[6-8])|8\d)\d{8,8}$/,
            required: true,
            message: '请输入正确的手机号',
            trigger: 'blur'
          }
        ],
        userEmail: [
          { required: true, message: '请输入邮箱', trigger: 'blur' },
          {
            pattern: /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/,
            required: true,
            message: '请输入正确的邮箱',
            trigger: 'blur'
          }
        ],
        userSex: [{ required: true, message: '请选择性别', trigger: 'blur' }]
      },
      // 删除用户
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      // 重置密码
      resetpsd: {
        userId: '',
        token: localStorage.getItem('logintoken')
      },
      // 请求数据参数
      uerInline: {
        page: 1,
        limit: 10,
        deptId: '',
        userName: '',
        userMobile: '',
        isLock: ''
      },
      //用户数据
      userData: [],
      // 数据权限
      UserDept: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 选中
      checkmenu: [],
      //参数role
      saveroleId: '',
      // 分页参数
      pagination: {
        currentPage: 1,
        pageSize:5,
        total:5
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  watch: {},
  created() {
    this.getdata(this.uerInline)
  },
  methods: {
    // 获取数据方法
    getdata(parameter) {
      this.loading = true
      //测试环境使用数据
      let res = {
        code: 0,
        msg: null,
        count:7,
        data: [
          {
            addUser: '1',
            editUser: '1',
            addTime: null,
            editTime: "2024年03月01日",
            userId: 1,
            systemNo: 'pmd',
            userName: 'admin',
            userPassword: 'e10adc3949ba59abbe56e057f20f883e',
            userRole: '高级管理员',
            userSex: '女',
            userMobile: '159-xxxx-xxxx',
            userEmail: 'admin@qq.com',
            isLock: 'N',
            deptId: 1,
            deptName: 'xxxx',
            roleId: 1
          },
          {
            addUser: '2',
            editUser: '2',
            addTime: null,
            editTime: "2024年03月01日",
            userId: 2,
            systemNo: 'mc',
            userName: 'test',
            userPassword: '5f4dcc3b5aa765d61d8327deb882cf99',
            userRole: '系统管理员',
            userSex: '男',
            userMobile: '188-xxxx-xxxx',
            userEmail: 'test@example.com',
            isLock: 'N',
            deptId: 2,
            deptName: 'xxxx',
            roleId: 2
          },
          {
            addUser: '3',
            editUser: '3',
            addTime: null,
            editTime: "2024年03月09日",
            userId: 3,
            systemNo: 'ec',
            userName: '明客',
            userPassword: '0192023a7bbd73250527102f08a0d3c8',
            userRole: '数据管理员',
            userSex: '男',
            userMobile: '134-xxxx-xxxx',
            userEmail: 'mingke@example.com',
            isLock: 'N',
            deptId: 3,
            deptName: 'xxxx',
            roleId: 3
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年03月22日",
            userId: 4,
            systemNo: null,
            userName: '智宇',
            userPassword: 'c4ca4238a0b923820dcc509a6f75849b',
            userRole: '用户',
            userSex: '男',
            userMobile: '178-xxxx-xxxx',
            userEmail: 'mingyu@example.com',
            isLock: 'N',
            deptId: 4,
            deptName: 'zxxxxx',
            roleId: 4
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年03月23日",
            userId: 5,
            systemNo: null,
            userName: '云访',
            userPassword: 'a94a8fe5ccb19ba61c4c0873d391e987982fbbd3',
            userRole: '用户',
            userSex: '女',
            userMobile: '135-xxxx-xxxx',
            userEmail: 'yunfang@example.com',
            isLock: 'N',
            deptId: 5,
            deptName: 'zxxxxx',
            roleId: 4
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年03月25日",
            userId: 6,
            systemNo: null,
            userName: '畅言',
            userPassword: '9f86d081884c7d659a2feaa0c55ad015',
            userRole: '用户',
            userSex: '女',
            userMobile: '135-xxxx-xxxx',
            userEmail: 'changyan@example.com',
            isLock: 'N',
            deptId: 6,
            deptName: 'zxxxxx',
            roleId: 4
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1526275128000,
            editTime: "2024年03月29日",
            userId: 7,
            systemNo: null,
            userName: '慧联',
            userPassword: '67e55b722da226b382a1e1cc6d4705c0',
            userRole: '用户',
            userSex: '男',
            userMobile: '132-xxxx-xxxx',
            userEmail: 'huilian@example.com',
            isLock: 'N',
            deptId: 7,
            deptName: 'zxxxxx',
            roleId: 4
          },
        ]
      }
      this.loading = false
      this.userData = res.data
      // 分页赋值
      this.pagination.currentPage = this.uerInline.page
      this.pagination.pageSize = this.uerInline.limit
      this.pagination.total = res.count
      // 测试环境  模拟数据结束  
      /***
       *  正式环境环境 调用接口
       */
      // 获取用户列表
      userList(parameter).then(res => {
        this.loading = false
        if (res.success == false) {
          this.$message({
            type: 'info',
            message: res.msg
          })
        } else {
          this.userData = res.data
          // 分页赋值
          this.pagination.currentPage = this.uerInline.page
          this.pagination.pageSize = this.uerInline.limit
          this.pagination.total = res.count
        }
      })
    },
    // 分页插件事件
    callFather(parm) {
      this.uerInline.page = parm.currentPage
      this.uerInline.limit = parm.pageSize
      this.getdata(this.uerInline)
    },
    //搜索事件
    search() {
      this.getdata(this.uerInline)
    },
    // 修改type
    editType: function(index, row) {
      this.loading = true
      let parm = {
        lock: '',
        userId: '',
        token: localStorage.getItem('logintoken')
      }
      parm.userId = row.userId
      let lock = row.isLock
      if (lock == 'N') {
        parm.lock = 'Y'
      } else {
        parm.lock = 'N'
      }
      // 修改状态
      userLock(parm).then(res => {
        this.loading = false
        if (res.success == false) {
          this.$message({
            type: 'info',
            message: res.msg
          })
        } else {
          this.$message({
            type: 'success',
            message: '状态修改成功'
          })
          this.getdata(this.uerInline)
        }
      })
    },
    //显示编辑界面
    handleEdit: function(index, row) {
      this.userFormVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '修改用户'
        this.userForm.userId = row.userId
        this.userForm.userName = row.userName
        this.userForm.userRole = row.userRole
        this.userForm.roleId = row.roleId
        this.userForm.userMobile = row.userMobile
        this.userForm.userEmail = row.userEmail
        this.userForm.userSex = row.userSex
      } else {
        this.title = '添加用户'
        this.userForm.userId = ''
        this.userForm.userName = ''
        this.userForm.userRole = ''
        this.userForm.roleId = ''
        this.userForm.userMobile = ''
        this.userForm.userEmail = ''
        this.userForm.userSex = ''
      }
    },
    // 编辑、添加提交方法
    submitForm(editData) {
      this.$refs[editData].validate(valid => {
        if (valid) {
          // 请求方法
          userSave(this.userForm)
            .then(res => {
              this.userFormVisible = false
              this.loading = false
              if (res.success) {
                this.getdata(this.uerInline)
                this.$message({
                  type: 'success',
                  message: '用户保存成功！'
                })
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.userFormVisible = false
              this.loading = false
              this.$message.error('用户保存失败，请稍后再试！')
            })
        } else {
          return false
        }
      })
    },
    handleClick(data, checked, node) {
      if (checked) {
        this.$refs.tree.setCheckedNodes([])
        this.$refs.tree.setCheckedNodes([data])
        this.unitparm.deptId = data.id
        this.unitparm.deptName = data.name
        //交叉点击节点
      } else {
      }
    },
    closeDialog(dialog) {
        this.userFormVisible = false
    },
    // 重置密码
    resetpwd(index, row) {
      this.resetpsd.userId = row.userId
      this.$confirm('确定要重置用户密码吗?', '重置密码', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          userPwd(this.resetpsd)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '重置用户密码成功！'
                })
                this.getdata(this.uerInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('重置用户密码失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '取消重置用户密码！'
          })
        })
    },
  }
}
</script>
 <!-- 角色权限管理 -->
 <template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>角色权限管理</el-breadcrumb-item>
    </el-breadcrumb>
    <el-form :inline="true" :model="uerInline" class="user-search">
      <el-form-item label="搜索：">
        <el-input size="small" v-model="uerInline.roleName" placeholder="输入角色权限名称"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input size="small" v-model="uerInline.roleNo" placeholder="输入角色权限代码"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="handleEdit()">添加</el-button>
      </el-form-item>
    </el-form>
    <el-table size="small" :data="listData" highlight-current-row v-loading="loading" border element-loading-text="拼命加载中" style="width: 100%;">
      <el-table-column align="center" type="selection" width="60">
      </el-table-column>
      <el-table-column sortable prop="roleName" label="角色权限名称" width="300">
      </el-table-column>
      <el-table-column sortable prop="roleNo" label="角色权限代码" width="300">
      </el-table-column>
      <el-table-column sortable prop="editTime" label="修改时间" width="300">
        <template slot-scope="scope">
          <div>{{scope.row.editTime}}</div>
        </template>
      </el-table-column>
      <el-table-column sortable prop="editUser" label="修改人" width="300">
      </el-table-column>
      <el-table-column align="center" label="操作" min-width="300">
        <template slot-scope="scope">
          <el-button size="mini" @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button size="mini" type="danger" @click="deleteUser(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <Pagination v-bind:child-msg="page" @callFather="callFather"></Pagination>
    <el-dialog :title="title" :visible.sync="editFormVisible" width="30%" @click='closeDialog("edit")'>
      <el-form label-width="120px" :model="editForm" ref="editForm" :rules="rules">
        <el-form-item label="系统编码" prop="systemNo">
          <el-input size="small" v-model="editForm.systemNo" auto-complete="off" placeholder="请输入系统编码"></el-input>
        </el-form-item>
        <el-form-item label="角色权限名称" prop="roleName">
          <el-input size="small" v-model="editForm.roleName" auto-complete="off" placeholder="请输入角色权限名称"></el-input>
        </el-form-item>
        <el-form-item label="角色权限代码" prop="roleNo">
          <el-input size="small" v-model="editForm.roleNo" auto-complete="off" placeholder="请输入角色权限代码"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click='closeDialog("edit")'>取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="submitForm('editForm')">保存</el-button>
      </div>
    </el-dialog>
    <!-- 菜单权限 -->
    <el-dialog title="菜单权限" :visible.sync="menuAccessshow" width="30%" @click='closeDialog("perm")'>
      <el-tree ref="tree" default-expand-all="" :data="RoleRight" :props="RoleRightProps" :default-checked-keys="checkmenu" node-key="id" show-checkbox>
      </el-tree>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click='closeDialog("perm")'>取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title" @click="menuSubmit">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {
  roleList,
  roleSave,
  roleDelete,
  rolePwd,
  RoleRightTree,
  RoleRightSave
} from '../../api/userMG'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      editFormVisible: false, //控制编辑页面显示与隐藏
      menuAccessshow: false, //控制数据权限显示与隐藏
      title: '添加',
      editForm: {
        roleId: '',
        systemNo: '',
        roleNo: '',
        roleName: '',
        token: localStorage.getItem('logintoken')
      },
      // rules 表单验证
      rules: {
        systemNo: [
          { required: true, message: '请输入系统编码', trigger: 'blur' }
        ],
        roleNo: [
          { required: true, message: '请输入角色权限代码', trigger: 'blur' }
        ],
        roleName: [
          { required: true, message: '请输入角色权限名称', trigger: 'blur' }
        ]
      },
      uerInline: {
        page: 1,
        limit: 10,
        varLable: '',
        varName: '',
        token: localStorage.getItem('logintoken')
      },
      // 删除
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      listData: [], //用户数据
      // 数据权限
      RoleRight: [],
      RoleRightProps: {
        children: 'children',
        label: 'name'
      },
      checkmenu: [],
      saveroleId: '',
      page: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    this.getPermissionData(this.uerInline)
  },
  methods: {
    // 获取角色权限列表
    getPermissionData(parameter) {
      // 模拟数据
      let res = {
        code: 0,
        msg: null,
        count: 5,
        data: [
          {
            addUser: 'admin',
            editUser: 'admin',
            addTime: 1519182004000,
            editTime: '2024年03月15日',
            roleId: 1,
            systemNo: 'pmd',
            roleNo: 'quan001',
            roleName: '高级管理员'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1521111376000,
            editTime:'2024年03月15日',
            roleId: 2,
            systemNo: 'order',
            roleNo: 'quan002',
            roleName: '系统管理员'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月18日',
            roleId: 3,
            systemNo: 'pm',
            roleNo: 'quan003',
            roleName: '数据管理员'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月19日',
            roleId: 4,
            systemNo: 'pm',
            roleNo: 'quan004',
            roleName: '用户'
          },
          {
            addUser: null,
            editUser: null,
            addTime: 1520678221000,
            editTime: '2024年03月20日',
            roleId: 5,
            systemNo: 'pm',
            roleNo: 'quan005',
            roleName: '测试'
          },
        ]
      }
      this.loading = false
      this.listData = res.data
      // 分页赋值
      this.page.currentPage = this.uerInline.page
      this.page.pageSize = this.uerInline.limit
      this.page.total = res.count
      // 测试环境  模拟数据结束  
      // 正式环境环境 调用接口
      roleList(parameter)
        .then(res => {
          this.loading = false
          if (res.success == false) {
            this.$message({
              type: 'info',
              message: res.msg
            })
          } else {
            this.listData = res.data
            // 分页赋值
            this.page.currentPage = this.uerInline.page
            this.page.pageSize = this.uerInline.limit
            this.page.total = res.count
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('获取角色权限列表失败，请稍后再试！')
        })
    },
    // 分页插件事件
    callFather(parm) {
      this.uerInline.page = parm.currentPage
      this.uerInline.limit = parm.pageSize
      this.getPermissionData(this.uerInline)
    },
    // 搜索事件
    search() {
      this.getPermissionData(this.uerInline)
    },
    //显示编辑界面
    handleEdit: function(index, row) {
      this.editFormVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '修改'
        this.editForm.roleId = row.roleId
        this.editForm.systemNo = row.systemNo
        this.editForm.roleNo = row.roleNo
        this.editForm.roleName = row.roleName
      } else {
        this.title = '添加'
        this.editForm.roleId = ''
        this.editForm.systemNo = ''
        this.editForm.roleNo = ''
        this.editForm.roleName = ''
      }
    },
    // 编辑、增加页面保存方法
    submitForm(editData) {
      this.$refs[editData].validate(valid => {
        if (valid) {
          roleSave(this.editForm)
            .then(res => {
              this.editFormVisible = false
              this.loading = false
              if (res.success) {
                this.getPermissionData(this.uerInline)
                this.$message({
                  type: 'success',
                  message: '角色权限保存成功！'
                })
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.editFormVisible = false
              this.loading = false
              this.$message.error('角色权限保存失败，请稍后再试！')
            })
        } else {
          return false
        }
      })
    },
    // 删除角色权限
    deleteUser(index, row) {
      this.$confirm('确定要删除吗?', '信息', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          roleDelete(row.roleId)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '角色权限已删除！'
                })
                this.getPermissionData(this.uerInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('角色权限删除失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    // 数据权限
    menuAccess: function(index, row) {
      this.menuAccessshow = true
      this.saveroleId = row.roleId
      RoleRightTree(row.roleId)
        .then(res => {
          if (res.data.success) {
            this.$message({
              type: 'success',
              message: '获取权限成功'
            })
            this.changemenu(res.data.data)
            this.RoleRight = this.changeArr(res.data.data)
          } else {
            this.$message({
              type: 'info',
              message: res.data.msg
            })
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('获取权限失败，请稍后再试！')
        })
    },
    // 选中菜单
    changemenu(arr) {
      let change = []
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].checked) {
          change.push(arr[i].id)
        }
      }
      this.checkmenu = change
    },
    // tree 递归
    changeArr(list) {
      var temptree = [],
        tree = [],
        items = []
      for (var i in list) {
        if (!temptree[list[i].id]) {
          var trow = {
            id: list[i].id,
            pId: list[i].pId,
            name: list[i].name,
            open: list[i].open,
            checked: list[i].checked,
            children: []
          }
          temptree[list[i].id] = trow
          items.push(trow)
        }
        if (list[i].uid > 0) {
          temptree[list[i].id]['children'].push({
            id: list[i].id,
            pId: list[i].pId,
            name: list[i].name,
            open: list[i].open,
            checked: list[i].checked,
            children: []
          })
        }
      }
      for (var j in items) {
        if (temptree[items[j].pId]) {
          temptree[items[j].pId]['children'].push(temptree[items[j].id])
        } else {
          tree.push(temptree[items[j].id])
        }
      }
      temptree = null
      items = null
      return tree
    },
    // 菜单权限-保存
    menuSubmit() {
      let parm = {
        roleId: this.saveroleId,
        moduleIds: ''
      }
      let node = this.$refs.tree.getCheckedNodes()
      let moduleIds = []
      if (node.length != 0) {
        for (let i = 0; i < node.length; i++) {
          moduleIds.push(node[i].id)
        }
        parm.moduleIds = JSON.stringify(moduleIds)
      }
      RoleRightSave(parm)
        .then(res => {
          if (res.success) {
            this.$message({
              type: 'success',
              message: '权限保存成功'
            })
            this.menuAccessshow = false
            this.getPermissionData(this.uerInline)
          } else {
            this.$message({
              type: 'info',
              message: res.msg
            })
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('权限保存失败，请稍后再试！')
        })
    },
    // 关闭编辑、增加弹出框
    closeDialog(dialog) {
      if (dialog == 'edit') {
        this.editFormVisible = false
      } else if (dialog == 'perm') {
        this.menuAccessshow = false
      }
    }
  }
}
</script>
<!-- 虚拟人列表 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>虚拟人列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-form :inline="true" :model="virtualInline" class="virtual-search">
      <el-form-item label="搜索：">
        <el-input size="small" v-model="virtualInline.name" placeholder="输入虚拟人名称"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input size="small" v-model="virtualInline.gender" placeholder="请输入性别"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" icon="el-icon-search" @click="search">搜索</el-button>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="virtualEdit()">新增</el-button>
      </el-form-item>
    </el-form>
    <el-table size="small" :data="virtualPeopleS" highlight-current-row v-loading="loading" border
      element-loading-text="拼命加载中" style="width: 95.2%;">
      <el-table-column align="center" type="selection" width="60">
      </el-table-column>
      <el-table-column align="center" prop="name" label="姓名" width="200">
      </el-table-column>
      <el-table-column align="center" prop="age" label="年龄" width="200">
      </el-table-column>
      <el-table-column align="center" prop="gender" label="性别" width="100">
      </el-table-column>
      <el-table-column align="center" prop="occupation" label="职业" width="200">
      </el-table-column>
      <el-table-column align="center" prop="createdDate" label="创建日期" width="200">
      </el-table-column>
      <el-table-column align="center" prop="lastLoginDate" label="最后登录日期" width="200">
      </el-table-column>
      <el-table-column align="center" label="操作" width="200">
        <template slot-scope="scope">
          <el-button size="mini" @click="virtualEdit(scope.$index, scope.row)">编辑</el-button>
          <el-button size="mini" type="danger" @click="deleteVirtual(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <Pagination v-bind:child-msg="pageparams" @callFather="callFather"></Pagination>
    <el-dialog :title="title" :visible.sync="virtualVisible" width="30%" @click="closeDialog">
      <el-form label-width="120px" :model="virtual" :rules="virtualRules" ref="virtual">
        <el-form-item  prop="name" label="姓名">
          <el-input size="small" v-model="virtual.id" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="age" label="年龄">
          <el-input size="small" v-model="virtual.name" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="gender" label="性别">
          <el-input size="small" v-model="virtual.category" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="occupation" label="职业">
          <el-input size="small" v-model="virtual.price" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="createdDate" label="创建日期">
          <el-input size="small" v-model="virtual.weight" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="lastLoginDate" label="最后登录日期">
          <el-input size="small" v-model="virtual.origin" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeDialog">取消</el-button>
        <el-button size="small" type="primary" :loading="loading" class="title"
          @click="submitVirtual('virtual')">保存</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
 import { virtualPeople, deptSave, virtualDelete } from '../../api'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      virtualVisible: false, //控制编辑页面显示与隐藏
      title: '添加',
      virtual: {
        name: '',  
        age: 0,  
        gender: '',  
        occupation: '',  
        createdDate: '',  
        lastLoginDate: '' ,
        token: localStorage.getItem('logintoken')
      },
      // virtualRules表单验证
      virtualRules: {
        name: [
          { required: true, message: '请输入虚拟人姓名', trigger: 'blur' }
        ],
        gender: [{ required: true, message: '请输入性别', trigger: 'blur' }],
      },
      virtualInline: {
        name:'',
        gender:'',
        page: 1,
        limit: 10,
        token: localStorage.getItem('logintoken')
      },
      // 删除
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      virtualPeopleS: [], //数据
      // 分页参数
      pageparams: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    this.getdata(this.virtualInline)
  },
  methods: {
    // 获取数据列表
    getdata(parameter) {
      this.loading = true
      // 模拟数据开始
      let res = {
        code: 0,
        msg: null,
        count: 41,
        data: [
        {  
        name: '虚拟人1',  
        age: 25,  
        gender: '男',  
        occupation: '售前客服',  
        createdDate: '2024-03-01',  
        lastLoginDate: '2024-03-20'  
      },  
      {  
        name: '虚拟人2',  
        age: 32,  
        gender: '女',  
        occupation: '售后客服',  
        createdDate: '2024-03-05',  
        lastLoginDate: '2024-03-23'  
      },  
      {  
        name: '虚拟人3',  
        age: 28,  
        gender: '男',  
        occupation: '在线客服',  
        createdDate: '2024-03-06',  
        lastLoginDate: '2024-03-30'  
      },  
      {  
        name: '虚拟人4',  
        age: 29,  
        gender: '女',  
        occupation: '社交媒体客服',  
        createdDate: '2024-03-07',  
        lastLoginDate: '2024-03-31'  
      },  
      {  
        name: '虚拟人5',  
        age: 35,  
        gender: '男',  
        occupation: '数据分析客服',  
        createdDate: '2024-03-07',  
        lastLoginDate: '2024-04-01'  
      },  
      {  
        name: '虚拟人6',  
        age: 27,  
        gender: '女',  
        occupation: '数据分析客服',  
        createdDate: '2024-03-08',  
        lastLoginDate: '2024-04-02'  
      },  
      {  
        name: '虚拟人7',  
        age: 31,  
        gender: '男',  
        occupation: '测试客服',  
        createdDate: '2024-03-08',  
        lastLoginDate: '2024-04-05'  
      },  
      {  
        name: '虚拟人8',  
        age: 26,  
        gender: '女',  
        occupation: '市场客服',  
        createdDate: '2024-03-10',  
        lastLoginDate: '2024-04-10'  
      },  
      {  
        name: '虚拟人9',  
        age: 33,  
        gender: '男',  
        occupation: '项目客服',  
        createdDate: '2024-03-10',  
        lastLoginDate: '2023-04-15'  
      },  
      {  
        name: '虚拟人10',  
        age: 30,  
        gender: '女',  
        occupation: '运维客服',  
        createdDate: '2024-03-11',  
        lastLoginDate: '2024-04-20'  
      }  
        ]
      }
      this.loading = false
      this.virtualPeopleS = res.data
      this.pageparams.currentPage = this.virtualInline.page
      this.pageparams.pageSize = this.virtualInline.limit
      this.pageparams.total = res.count
      // 测试环境  模拟数据结束  
      /***
       *  正式环境环境 调用接口
       */
      virtualPeople(parameter)
        .then(res => {
          this.loading = false
          if (res.success == false) {
            this.$message({
              type: 'info',
              message: res.msg
            })
          } else {
            this.virtualPeopleS = res.data
            // 分页赋值
            this.pageparams.currentPage = this.virtualInline.page
            this.pageparams.pageSize = this.virtualInline.limit
            this.pageparams.total = res.count
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('虚拟人列表数据加载失败，请稍后再试！')
        })
    },
    // 分页插件事件
    callFather(parm) {
      this.virtualInline.page = parm.currentPage
      this.virtualInline.limit = parm.pageSize
      this.getdata(this.virtualInline)
    },
    // 搜索事件
    search() {
      this.getdata(this.virtualInline)
    },
    //添加、编辑
    virtualEdit: function (index, row) {
      this.virtualVisible = true
      if (row != undefined && row != 'undefined') {
        this.title = '编辑'
        this.virtual.roomNumber = row.roomNumber
        this.virtual.roomName = row.roomName
        this.virtual.bookingStatus = row.bookingStatus
        this.virtual.usageStatus = row.usageStatus
        this.virtual.virtualType = row.virtualType
        this.virtual.virtualTime = row.virtualTime
      } else {
        this.title = '添加'
        this.virtual.roomNumber = ''
        this.virtual.roomName = ''
        this.virtual.bookingStatus = ''
        this.virtual.usageStatus = ''
        this.virtual.virtualType = ''
        this.virtual.virtualTime = ''
      }
    },
    // 编辑、增加页面保存方法
    submitVirtual(editData) {
      this.$refs[editData].validate(valid => {
        if (valid) {
          deptSave(this.virtual)
            .then(res => {
              this.virtualVisible = false
              this.loading = false
              if (res.success) {
                this.getdata(this.virtualInline)
                this.$message({
                  type: 'success',
                  message: '虚拟人保存成功！'
                })
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.virtualVisible = false
              this.loading = false
              this.$message.error('虚拟人保存失败，请稍后再试！')
            })
        } else {
          return false
        }
      })
    },
    // 删除虚拟人
    deleteVirtual(index, row) {
      this.$confirm(`确定要删除虚拟人吗?`, '删除虚拟人', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          virtualDelete(row.virtualBankId)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '虚拟人已删除!'
                })
                this.getdata(this.virtualInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('虚拟人删除失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          })
        })
    },
    // 关闭编辑、增加弹框
    closeDialog() {
      this.virtualVisible = false
    }
  }
}
</script>
<!-- 虚拟人详情 -->
<template>
  <div class="virtual-person">
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>虚拟人详情</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="virtual-person-details">
    <div class="header">
      <h2>{{ virtualPerson.name }}</h2>
      <p>{{ virtualPerson.briefIntroduction }}</p>
    </div>
    <!-- 基本信息 -->
    <div class="basic-info">
      <el-form>
        <el-form-item label="年龄">
          <span>{{ virtualPerson.age }}</span>
        </el-form-item>
        <el-form-item label="性别">
          <span>{{ virtualPerson.gender }}</span>
        </el-form-item>
        <el-form-item label="职业">
          <span>{{ virtualPerson.occupation }}</span>
        </el-form-item>
      </el-form>
    </div>
    <!-- 技能展示 -->
    <div class="skills">
      <el-tag v-for="skill in virtualPerson.skills" :key="skill" @click="showSkillDetails(skill)">
        {{ skill }}
      </el-tag>
    </div>
    <!-- 活动记录 -->
    <div class="activity-records">
      <el-table :data="activityRecords" style="width: 100%" @sort-change="handleSortChange">
        <el-table-column prop="timestamp" label="时间戳" sortable></el-table-column>
        <el-table-column prop="activity" label="活动"></el-table-column>
      </el-table>
    </div>
    <!-- 互动区 -->
    <div class="interaction">
      <div class="interaction-title">虚拟人客服互动区域:</div>
      <!-- <div></div> -->
      <el-input v-model="message" placeholder="请输入消息"></el-input>
      <el-button class="interaction-botton"  @click="sendMessage">发送</el-button>
    </div>
    <!-- 技能详情弹窗 -->
    <el-dialog :visible.sync="skillDetailsVisible" width="50%">
      <span>技能详情：{{ selectedSkill }}</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="skillDetailsVisible = false">关闭</el-button>
      </span>
    </el-dialog>
  </div>
  </div>
</template>
<script>
 import { details,  } from '../../api'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      virtualPerson: {
        name: '虚拟人客服',
        briefIntroduction: '虚拟客服简介',
        age: 25,
        gender: '男',
        occupation: '职业',
        skills: [
          '多语言主持服务', 
          '精准的台词控制和情感表达', 
          '高度的灵活性和稳定性',
          '强大的交互性'],
      },
      activityRecords: [
        { timestamp: '2024-03-01', activity: '活动1:实时互动与引导' },
        { timestamp: '2024-04-05', activity: '活动2:智能问答与反馈收集' },
        { timestamp: '2024-04-10', activity: '活动3:个性化推荐与体验' },
        { timestamp: '2024-04-20', activity: '活动4:数据分析与优化' },
      ],
      message: '',
      skillDetailsVisible: false,
      selectedSkill: '',
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    // this.getdata()
  },
  methods: {
    // 获取数据列表
    getdata(parameter) {
      /***
       *  正式环境环境 调用接口
       */
       details(parameter)
        .then(res => {
          if (res.success == -1) {
            this.$message({
              type: 'info',
              message: res.msg
            })
          } else {
            this.virtualPerson = res.data
          }
        })
        .catch(err => {
          this.$message.error('加载失败，请稍后再试！')
        })
    },
    showSkillDetails(skill) {  
      this.selectedSkill = skill;  
      this.skillDetailsVisible = true;  
    },  
    sendMessage() {  
      // 处理发送消息的逻辑  
      alert(`发送消息: ${this.message}`);  
      this.message = '';  
    },  
    handleSortChange({ column, prop, order }) {  
      // 处理表格排序逻辑  
      console.log(`排序列: ${prop}, 排序方式: ${order}`);  
    },  
  },  
}
</script>
<style scoped>  
.virtual-person-details {  
  padding: 20px;  
  margin: 0 auto; 
  margin-top: 20px;
  border-radius: 8px;
  border: 1px solid rgb(245, 227, 227);
  height: 83vh;
  width:90%;
  background-color: #f7f4f4;
}   
.header {  
  display: flex;  
  align-items: center;  
  justify-content: space-between;  
  margin-top: 20px;  
  margin-bottom: 20px;  
}  
.header .el-avatar {  
  margin-right: 10px; /* 头像与名字之间的间距 */  
}  
.header h2 {  
  font-size: 20px;  
  font-weight: bold;  
  margin: 0;  
}  
.header p {  
  font-size: 16px;  
  color: #666;  
  margin: 0;  
}  
.basic-info {  
  margin-bottom: 20px;  
}  
.basic-info .el-form-item {  
  margin-bottom: 10px;  
}  
.basic-info .el-form-item label {  
  font-weight: bold;  
}  
.skills {  
  display: flex;  
  flex-wrap: wrap;  
  margin-bottom: 20px;  
}  
.skills .el-tag {  
  margin-right: 5px;  
  margin-bottom: 5px;  
}  
.activity-records {  
  width: 100%;  
  margin-bottom: 20px;  
}  
.interaction-title,.interaction-botton{
    margin-top: 20px;
    margin-bottom: 20px;
  }  
.interaction .el-input {  
  flex: 1;  
  margin-right: 10px;  
}  
.interaction .el-button {  
  flex-shrink: 0;  
}  
.el-dialog__wrapper {  
  z-index: 9999; /* 确保弹窗显示在最上层 */  
}  
</style>
<!-- 交互记录 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>交互记录</el-breadcrumb-item>
    </el-breadcrumb>
    <el-form :inline="true" :model="recordsInline" class="surgery-search">
      <el-form-item label="搜索：">
        <el-input size="small" v-model="recordsInline.userId" placeholder="用户ID"></el-input>
      </el-form-item>
      <el-form-item label="">
        <el-input size="small" v-model="recordsInline.time" placeholder="时间"></el-input>
      </el-form-item>
      <el-form-item>
        <el-button size="small" type="primary" icon="el-icon-search" @click="search">搜索</el-button>
      </el-form-item>
    </el-form>
    <el-table size="small" :data="interactionRecords" highlight-current-row v-loading="loading" brecordsI
      element-loading-text="拼命加载中" style="width: 100%;">
      <el-table-column align="center" type="selection" width="50">
      </el-table-column>
      <el-table-column align="center" prop="date" label="日期" width="200">
      </el-table-column>
      <el-table-column align="center" prop="time" label="时间" width="100">
      </el-table-column>
      <el-table-column align="center" prop="userId" label="用户ID" width="100">
      </el-table-column>
      <el-table-column align="center" prop="question" label="问题描述" width="200">
      </el-table-column>
      <el-table-column align="center" prop="response" label="回复内容" width="300">
      </el-table-column>
      <el-table-column align="center" prop="duration" label="交互时长" width="100">
      </el-table-column>
      <el-table-column align="center" prop="satisfaction" label="满意度评分" width="`00">
      </el-table-column>
      <el-table-column align="center" prop="remarks" label="备注" width="200">
      </el-table-column>
      <el-table-column align="center" label="操作" width="200">
        <template slot-scope="scope">
          <el-button size="mini" @click="recordsIEdit(scope.$index, scope.row)">查看详情</el-button>
          <el-button size="mini" type="danger" @click="deleterecordsI(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <Pagination v-bind:child-msg="pageparm" @callFather="callFather"></Pagination>
    <!-- 查看详情界面 -->
    <el-dialog :title="title" :visible.sync="recordVisible" width="40%" @click="closeDialog">
      <el-form label-width="120px" :model="recordsI" ref="recordsI">
        <el-form-item prop="date" label="日期">
          <el-input size="small" :disabled="true" v-model="recordsI.date" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="time" label="时间">
          <el-input size="small" :disabled="true" v-model="recordsI.time" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="userId" label="用户ID">
          <el-input size="small" :disabled="true" v-model="recordsI.userId" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="question" label="问题描述" width="100">
          <el-input size="small" :disabled="true" v-model="recordsI.question" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="response" label="回复内容">
          <el-input size="small" :disabled="true" v-model="recordsI.response" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="duration" label="交互时长">
          <el-input size="small" :disabled="true" v-model="recordsI.duration" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="satisfaction" label="满意度评分">
          <el-input size="small" :disabled="true" v-model="recordsI.satisfaction" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="remarks" label="备注">
          <el-input size="small" :disabled="true" v-model="recordsI.remarks" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeDialog">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {recordsData,recordsISave,recordsIDelete } from '../../api'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      recordVisible: false, //控制编辑页面显示与隐藏
      title: '添加',
      recordsI: {
        date: '',
        time: '',
        userId: '',
        question: '',
        response: '',
        duration: '',
        satisfaction: '',
        remarks: '',
        token: localStorage.getItem('logintoken')
      },
      recordsInline: {
        userId: '',
        time: '',
        page: 1,
        limit: 10,
        token: localStorage.getItem('logintoken')
      },
      // 删除
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      interactionRecords: [], //数据
      // 分页参数
      pageparm: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    this.getdata(this.recordsInline)
  },
  methods: {
    // 获取数据列表
    getdata(recordContent) {
      this.loading = true
      // 模拟数据开始
      let res = {
        code: 0,
        msg: null,
        count: 39,
        data: [
          {
            date: '2024-03-01',
            time: '09:30',
            userId: 'U1234',
            question: '如何设置广告页面的背景色？',
            response: '您可以在广告页面的CSS样式中设置background-color属性来改变背景色。',
            duration: '00:01:45',
            satisfaction: '5',
            remarks: '用户问题得到解决，对回答表示满意。'
          },
          {
            date: '2024-03-02',
            time: '14:15',
            userId: 'U5678',
            question: '广告图片上传失败，如何解决？',
            response: '请检查图片格式和大小是否符合要求，同时确保网络连接正常。如仍有问题，请联系客服支持。',
            duration: '00:02:30',
            satisfaction: '4',
            remarks: '用户按照建议操作后成功上传图片，但希望有更详细的错误提示。'
          },
          {
            date: '2024-03-08',
            time: '10:45',
            userId: 'U9101',
            question: '如何调整广告轮播图的播放速度？',
            response: '您可以在广告轮播组件的配置中设置interval属性来调整播放速度，数值越小速度越快。',
            duration: '00:01:50',
            satisfaction: '5',
            remarks: '用户理解并成功调整播放速度，表示满意。'
          },
          {
            date: '2024-03-15',
            time: '15:00',
            userId: 'U2345',
            question: '广告链接点击后无反应，怎么办？',
            response: '请检查广告链接是否有效，同时确保浏览器兼容性和网络连接正常。如问题持续，请提供详细的错误日志以便排查。',
            duration: '00:02:10',
            satisfaction: '3',
            remarks: '用户反映问题依然存在，需要进一步排查。'
          },
          {
            date: '2024-03-22',
            time: '08:30',
            userId: 'U6789',
            question: '如何设置广告位的目标跳转页面？',
            response: '您可以在广告位的配置中设置targetUrl属性，指定跳转页面的URL地址。',
            duration: '00:01:30',
            satisfaction: '5',
            remarks: '用户按照指引成功设置，对回答表示满意。'
          },
          {
            date: '2024-03-29',
            time: '13:15',
            userId: 'U3456',
            question: '广告数据如何实时更新？',
            response: '广告数据的实时更新通常依赖于后端服务的数据推送或轮询机制。请确保后端服务正常运行，并与前端建立有效的数据同步机制。',
            duration: '00:02:00',
            satisfaction: '4',
            remarks: '用户希望了解更多关于数据更新的技术细节。'
          },
          {
            date: '2024-04-05',
            time: '11:00',
            userId: 'U7890',
            question: '如何调整广告文案的字体和大小？',
            response: '您可以在广告文案的CSS样式中设置font-family和font-size属性来调整字体和大小。',
            duration: '00:01:55',
            satisfaction: '5',
            remarks: '用户成功调整文案样式，表示满意。'
          },
          {
            date: '2024-04-12',
            time: '16:30',
            userId: 'U4567',
            question: '广告效果数据如何分析？',
            response: '您可以使用我们提供的广告效果分析工具，对点击率、转化率等指标进行深入分析，以优化广告策略。',
            duration: '00:02:20',
            satisfaction: '4',
            remarks: '用户成功调整广告效果，表示满意。'
          },
          {
            date: '2024-04-19',
            time: '11:15',
            userId: 'U0987',
            question: '广告推广活动的预算如何设置？',
            response: '您可以在广告推广活动的创建页面中设置预算，并根据预算限制投放广告的频次和范围。',
            duration: '00:02:15',
            satisfaction: '4',
            remarks: '用户希望有更详细的预算设置建议，以优化投放效果。'
          },
          {
            date: '2024-04-20',
            time: '15:45',
            userId: 'U6543',
            question: '如何设置广告位的地域定向投放？',
            response: '您可以在广告位的投放设置中，选择特定的地域范围进行定向投放，以提高广告效果和转化率。',
            duration: '00:01:30',
            satisfaction: '5',
            remarks: '用户成功设置地域定向投放，对回答表示满意。'
          },
        ]
      }
      this.loading = false
      this.interactionRecords = res.data
      this.pageparm.currentPage = this.recordsInline.page
      this.pageparm.pageSize = this.recordsInline.limit
      this.pageparm.total = res.count
      // 测试环境  模拟数据结束  
      /***
       *  正式环境环境 调用接口
       */
       recordsData(recordContent)
          .then(res => {
            this.loading = false
            if (res.success == false) {
              this.$message({
                type: 'info',
                message: res.msg
              })
            } else {
              this.interactionRecords = res.data
              // 分页赋值
              this.pageparm.currentPage = this.recordsInline.page
              this.pageparm.pageSize = this.recordsInline.limit
              this.pageparm.total = res.count
            }
          })
          .catch(err => {
            this.loading = false
            this.$message.error('交互记录加载失败，请稍后再试！')
          })
    },
    // 分页插件事件
    callFather(parm) {
      this.recordsInline.page = parm.currentPage
      this.recordsInline.limit = parm.pageSize
      this.getdata(this.recordsInline)
    },
    // 搜索事件
    search() {
      this.getdata(this.recordsInline)
    },
    //添加、编辑
    recordsIEdit: function (index, row) {
      this.recordVisible = true
      this.title = '查看详情'
      this.recordsI.date = row.date
      this.recordsI.time = row.time
      this.recordsI.userId = row.userId
      this.recordsI.question = row.question
      this.recordsI.response = row.response
      this.recordsI.duration = row.duration
      this.recordsI.satisfaction = row.satisfaction
      this.recordsI.remarks = row.remarks
    },
    // 删除交互记录
    deleterecordsI(index, row) {
      this.$confirm(`确定要删除交互记录吗?`, '删除交互记录', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          recordsIDelete(row.recordsIBankId)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '交互记录已删除!'
                })
                this.getdata(this.recordsInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('交互记录删除失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除交互记录'
          })
        })
    },
    // 关闭弹框
    closeDialog() {
      this.recordVisible = false
    }
  }
}
</script>
<!-- 交互详情 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>交互详情</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="interaction-details">
      <el-card class="interaction-card">
        <div slot="header" class="clearfix">
          <span>交互详情</span>
          <el-button type="text" @click="goBack">返回</el-button>
        </div>
        <div v-if="interaction">
          <el-row :gutter="20">
            <el-col :span="12">
              <strong>日期:</strong>
              <span>{{ interaction.date }}</span>
            </el-col>
            <el-col :span="12">
              <strong>用户:</strong>
              <span>{{ interaction.user.name }}</span>
            </el-col>
            <el-col :span="12">
              <strong>用户Email:</strong>
              <span>{{ interaction.user.email }}</span>
            </el-col>
            <el-col :span="12">
              <strong>用户头像:</strong>
              <span>{{ interaction.user.avatarUrl }}</span>
            </el-col>
          </el-row>
          <el-tabs v-model="activeTab" @tab-click="handleTabClick">
            <el-tab-pane label="问题" name="question">
              <el-input v-model="interaction.question"   :rows="10" type="textarea" ></el-input>
            </el-tab-pane>
            <el-tab-pane label="响应回复" name="response">
              <el-input v-model="interaction.response.text" :rows="10"  type="textarea"></el-input>
            </el-tab-pane>
            <!-- 其他tabs -->
          </el-tabs>
          <el-row class="other-info" :gutter="20">
            <el-col :span="12">
              <strong>满意度:</strong>
              <el-tag>{{ interaction.satisfaction }}</el-tag>
            </el-col>
            <el-col :span="12">
              <strong>满意度进度:</strong>
              <el-progress :percentage="interaction.percentage"></el-progress>
            </el-col>
          </el-row>
          <el-row class="action-row" :gutter="20" justify="end">
            <el-button type="primary" @click="editInteraction">编辑</el-button>
            <el-button type="danger" @click="deleteInteraction">删除</el-button>
          </el-row>
        </div>
        <div v-else>
          <el-alert type="warning" title="无交互数据" description="尚未加载到交互数据。" show-icon></el-alert>
        </div>
      </el-card>
    </div>
  </div>
</template>  
<script>
import { login } from '../../api/userMG';
 import { getInteraction } from '../../api/userMG'
export default {
  data() {
    return {
      interaction:null, // 用于存储交互数据的对象  
      activeTab: 'question', // 当前激活的tab 
    };
  },
  created() {
    this.getDate();
  },
  methods: {
    getDate() {
      //测试环境 模拟数据
      this.interaction = {
        id: 1, // 交互的唯一标识符  
        date: '2023-04-01T12:00:00Z', // ISO 8601格式的交互日期和时间  
        user: {
          id: 101,
          name: 'John Doe',
          email: 'johndoe@example.com',
          avatarUrl: 'https://example.com/avatar.png' // 用户头像URL  
        },
        question: '我购买的产品出现了故障，应该如何处理？', // 用户的问题或请求  
        response: {
          text: '非常抱歉听到您的产品出现故障。请您联系我们的客服团队，他们将为您提供进一步的帮助和解决方案。', // 对用户问题的响应文本  
          date: '2023-04-01T13:30:00Z', // 响应的日期和时间  
          agent: {
            id: 201,
            name: 'Jane Smith',
            email: 'janesmith@example.com'
          } // 响应的客服人员信息  
        },
        attachments: [ // 相关的附件列表  
          {
            id: 'attachment1',
            url: 'https://example.com/attachment1.jpg',
            type: 'image',
            description: '故障产品的照片'
          },
          {
            id: 'attachment2',
            url: 'https://example.com/log.txt',
            type: 'text',
            description: '产品日志文件'
          }
        ],
        satisfaction: 4 ,// 用户满意度评级，假设是1到5的整数 
        percentage: '80',
        tags: ['产品故障', '客服响应'], // 与交互相关的标签列表  
        status: 'resolved', // 交互的状态
      },
      console.log(this.interaction,"this.interaction");
      //正式环境使用接口请求数据
      getInteraction(parameter)
        .then(res => {
          this.loading = false
          if (res.success == false) {
            this.$message({
              type: 'info',
              message: res.msg
            })
          } else {
            this.interaction = res.data
          }
        })
        .catch(err => {
          this.loading = false
          this.$message.error('数据加载失败，请稍后再试！')
        })
    },
    goBack() {
      this.$router.go(-1); // 返回上一页  
    },
    async editInteraction() {
      // 处理编辑交互的逻辑  
      try {  
      const formData = {  
        question: this.interaction.question,  
        response: this.interaction.response,  
        satisfaction: this.interaction.satisfaction,  
      };  
      // 发送PUT请求到后端API来更新交互  
      const response = await this.$api.put(`/interactions/${this.interaction.id}`, formData);  
      // 检查响应状态，并更新本地数据（如果需要）  
      if (response.data && response.data.success) {  
        // 假设后端返回了更新后的交互详情  
        this.interaction = { ...this.interaction, ...response.data.interaction };  
        // 显示成功消息或进行其他操作  
        this.$message({ message: '交互信息已更新成功', type: 'success' });  
      } else {  
        // 处理错误情况  
        this.$message.error('更新交互信息时出错');  
      }  
    } catch (error) {  
      // 处理网络错误或其他异常  
      console.error('更新交互信息时发生错误:', error);  
      this.$message.error('网络错误，请稍后再试');  
    }  
    },
    async deleteInteraction() {
      // 处理删除交互的逻辑 
      try {  
      const interactionId = this.interaction.id;   
      const response = await this.$api.delete(`/interactions/${interactionId}`);  
      if (response.data && response.data.success) {  
        this.interaction = null; 
        this.$message({ message: '交互已成功删除', type: 'success' });  
      } else {  
        // 处理删除失败的情况  
        this.$message.error('删除交互时出错');  
      }  
    } catch (error) {  
      // 处理网络错误或其他异常  
      console.error('删除交互时发生错误:', error);  
      this.$message.error('网络错误，请稍后再试');  
    }   
    },
    handleTabClick(tab, event) {
      // 处理tab点击事件
      // 阻止标签页默认的点击事件行为，比如跳转链接  
    event.preventDefault();  
      // 存储当前激活的标签页的标识  
      this.activeTab =  tab.name;
      // 清除所有标签页的激活状态  
      this.tabs.forEach(t => {  
        t.active = false;  
      });  
      // 设置被点击的标签页为激活状态  
      tab.active = true;    
    },
  },
};  
</script>  
<style scoped>
.interaction-details{
   margin-top: 30px;
   height: 80vh;
}
.interaction-details::v-deep .el-tabs__item {
  padding: 0px;
  width: 170px;
  text-align: center;
  }
  .el-tabs__item {
  text-align: center;
}
.el-tabs__item.is-top:last-child {
  padding: 0 20px;
}
.order-detail {
  margin-top: 30px;
}
.text-center {
  margin-top: 20px;
}
.el-col{
  margin-top: 20px;
  margin-bottom: 20px;
}
.order-detail-page {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
  font-family: Arial, sans-serif;
}
.order-summary {
  margin-bottom: 20px;
  border-bottom: 1px solid #ccc;
  padding-bottom: 10px;
}
.order-summary dl {
  display: flex;
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
}
.order-summary dt,
.order-summary dd {
  flex: 1 0 50%;
  margin: 0;
  padding: 5px 0;
}
.order-summary dt {
  font-weight: bold;
}
.order-items {
  width: 100%;
  border-collapse: collapse;
  margin-top: 20px;
}
.order-items th,
.order-items td {
  padding: 8px;
  text-align: left;
  border-bottom: 1px solid #ddd;
}
.order-items th {
  background-color: #f2f2f2;
}
.order-actions {
  margin-top: 20px;
}
.order-actions button {
  padding: 10px 20px;
  font-size: 16px;
  background-color: #4CAF50;
  /* Green */
  border: none;
  color: white;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  font-size: 16px;
  margin: 4px 2px;
  cursor: pointer;
  transition-duration: 0.4s;
}
.order-actions button:hover {
  background-color: #45a049;
  /* Dark Green */
  color: white;
}
</style>
<!-- 交互分析 -->
<template>
  <div class="interaction-analysis">
    <el-container>
      <el-header>虚拟人交互客服系统 - 交互分析</el-header>
      <el-main>
        <div class="chart-container">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>交互次数统计</span>
              <el-button style="float: right; padding: 3px 0" type="text"
                >查看更多</el-button
              >
            </div>
            <div v-if="chartDataLoaded">
              <div ref="myChart" style="width: 100%; height: 400px"></div>
            </div>
          </el-card>
        </div>
        <!-- 数据列表展示区域 -->
        <div class="data-list-container">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>交互数据列表</span>
            </div>
            <el-table
              :data="analysis"
              style="width: 100%"
              @selection-change="handleSelectionChange"
            >
              <el-table-column type="selection" width="55"></el-table-column>
              <el-table-column
                prop="date"
                label="日期"
                width="280"
              ></el-table-column>
              <el-table-column
                prop="label"
                label="平均响应时间 (秒)"
                width="180"
              ></el-table-column>
              <el-table-column
                prop="interactions"
                label="交互次数"
                width="220"
              ></el-table-column>
              <el-table-column
                prop="satisfaction"
                label="满意度"
                width="220"
              ></el-table-column>
              <!-- 其他数据列 -->
            </el-table>
            <el-pagination
              @size-change="handleSizeChange"
              @current-change="handleCurrentChange"
              :current-page="pagination.currentPage"
              :page-sizes="[10, 20, 50, 100]"
              :page-size="pagination.pageSize"
              layout="total, sizes, prev, pager, next, jumper"
              :total="pagination.total"
            ></el-pagination>
          </el-card>
        </div>
      </el-main>
    </el-container>
  </div>
</template> 
<script type="text/ecmascript-6">
import Chart from "echarts";
export default {
  name: "InteractionAnalysis",
  data() {
    return {
      filters: {
        dateRange: "",
      },
      analysis: [], // 表格数据
      chartData: null, // 图表数据
      chartDataLoaded: true,
      pagination: {
        currentPage: 1,
        pageSize: 10,
        total: 0,
      },
      multipleSelection: [], // 表格多选数据
    };
  },
  created() {
    this.getdata();
  },
  mounted() {
    // 初始化图表
    this.initChart();
  },
  methods: {
    // 获取数据列表
    getdata(recordContent) {
      this.loading = true;
      // 模拟数据开始
      let res = {
        columns: [
          { name: "日期", label: "日期" },
          { name: "交互次数", label: "交互次数" },
          { name: "平均响应时间", label: "平均响应时间 (秒)" },
          { name: "满意度", label: "满意度 (%)" },
        ],
        data: [
          {date: "2023-04-01", interactions: 120, label: 5.2, satisfaction: 85 },
          { date: "2023-04-02", interactions: 150, label: 4.8, satisfaction: 88 },
          { date: "2023-04-03", interactions: 90, label: 5.5, satisfaction: 90 },
          { date: "2023-04-04", interactions: 110, label: 5.0, satisfaction: 89 },
          { date: "2023-04-05", interactions: 130, label: 4.9, satisfaction: 87 },
        ],
      };
      this.loading = false;
      this.analysis = res.data;
      // 正式环境环境 调用接口
       this.fetchData(); 
    },
    // 初始化图表
    initChart() {
      this.chartDataLoaded = true;
      const chartDom = this.$refs.myChart;
      const myChart = Chart.init(chartDom);
      // 设置图表配置项和数据
      const option = {
        // 标题
        title: {
          text: "虚拟人交互客服系统交互分析",
          subtext: "基于时间段的交互次数与满意度",
          left: "center",
        },
        // 提示框组件
        tooltip: {
          trigger: "axis",
          axisPointer: {
            type: "shadow",
          },
        },
        grid: {
          left: "3%",
          right: "4%",
          bottom: "3%",
          containLabel: true,
        },
        // x轴
        xAxis: {
          type: "category",
          data: [
            "2024-04-01",
            "2024-04-02",
            "2024-04-03",
            "2024-04-04",
            "2024-04-05",
          ], 
        },
        // y轴
        yAxis: {
          type: "value",
        },
        // 系列列表
        series: [
          {
            name: "交互次数",
            type: "bar", // 柱状图
            data: [120, 200, 150, 180, 158], // 交互次数数据
          },
          {
            name: "满意度",
            type: "line", // 折线图
            data: [85, 90, 88, 92, 97], // 满意度数据，
          },
        ],
      };
      myChart.setOption(option);
    },
    // 获取数据
    fetchData() {
      // 发送请求获取数据
      this.fetchInteractionData(this.filters.dateRange)
        .then((response) => {
          this.tableData = response.tableData;
          this.chartData = response.chartData;
          this.pagination.total = response.total;
          this.initChart(); // 如果有新的图表数据，重新初始化图表
        })
        .catch((error) => {
          console.error("Error fetching data:", error);
        });
    },
    // 处理表格多选数据变化
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },
    // 处理分页大小变化
    handleSizeChange(val) {
      this.pagination.pageSize = val;
      this.fetchData(); // 重新获取数据
    },
    // 处理分页当前页变化
    handleCurrentChange(val) {
      this.pagination.currentPage = val;
      this.fetchData(); // 重新获取数据
    },
  },
};
</script>
<!-- 知识库列表 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>知识库列表</el-breadcrumb-item>
    </el-breadcrumb>
    <el-table size="small" :data="lists" highlight-current-row v-loading="loading" bknowledge
      element-loading-text="拼命加载中" style="width: 100%;">
      <el-table-column align="center" type="selection" width="50">
      </el-table-column>
      <el-table-column align="center" prop="date" label="日期" width="200">
      </el-table-column>
      <el-table-column align="center" prop="category" label="问题分类"  width="100">
      </el-table-column>
      <el-table-column align="center" prop="description" label="问题描述"  width="200">
      </el-table-column>
      <el-table-column align="center" prop="solution" label="解决方案" width="200">
      </el-table-column>
      <el-table-column align="center" prop="product" label="关联产品" width="200">
      </el-table-column>
      <el-table-column align="center" prop="interactionCount" label="交互次数" width="100">
      </el-table-column>
      <el-table-column align="center" prop="satisfaction" label="满意度" width="`00">
      </el-table-column>
      <el-table-column align="center" label="操作" width="200">
        <template slot-scope="scope">
          <el-button size="mini" @click="knowledgeEdit(scope.$index, scope.row)">查看</el-button>
          <el-button size="mini" type="danger" @click="deleteknowledge(scope.$index, scope.row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
    <!-- 分页组件 -->
    <Pagination v-bind:child-msg="paging" @callFather="callFather"></Pagination>
    <!-- 查看详情界面 -->
    <el-dialog :title="title" :visible.sync="recordVisible" width="40%" @click="closeDialog">
      <el-form label-width="120px" :model="knowledge" ref="knowledge">
        <el-form-item prop="date" label="日期">
          <el-input size="small" :disabled="true" v-model="knowledge.date" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="time" label="时间">
          <el-input size="small" :disabled="true" v-model="knowledge.time" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="userId" label="用户ID">
          <el-input size="small" :disabled="true" v-model="knowledge.userId" auto-complete="off" placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="question" label="问题描述" width="200">
          <el-input size="small" :disabled="true" v-model="knowledge.question" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="response" label="回复内容">
          <el-input size="small" :disabled="true" v-model="knowledge.response" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="duration" label="交互时长">
          <el-input size="small" :disabled="true" v-model="knowledge.duration" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="satisfaction" label="满意度评分">
          <el-input size="small" :disabled="true" v-model="knowledge.satisfaction" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
        <el-form-item prop="remarks" label="备注">
          <el-input size="small" :disabled="true" v-model="knowledge.remarks" auto-complete="off"
            placeholder="请输入"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button size="small" @click="closeDialog">取消</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import {knowledgeData,knowledgeSave,knowledgeDelete } from '../../api'
import Pagination from '../../components/Pagination'
export default {
  data() {
    return {
      nshow: true, //switch开启
      fshow: false, //switch关闭
      loading: false, //是显示加载
      recordVisible: false, //控制编辑页面显示与隐藏
      title: '添加',
      knowledge: {
        "date": "",  
      "category": "",  
      "description": "",  
      "solution": "",  
      "product": "",  
      "interactionCount":0 ,  
      "satisfaction": "" ,
        token: localStorage.getItem('logintoken')
      },
      listInline: {
        userId: '',
        time: '',
        page: 1,
        limit: 10,
        token: localStorage.getItem('logintoken')
      },
      // 删除
      seletedata: {
        ids: '',
        token: localStorage.getItem('logintoken')
      },
      lists: [], //数据
      // 分页参数
      paging: {
        currentPage: 1,
        pageSize: 10,
        total: 10
      }
    }
  },
  // 注册组件
  components: {
    Pagination
  },
  created() {
    this.getdata(this.listInline)
  },
  methods: {
    // 获取数据列表
    getdata(recordContent) {
      this.loading = true
      // 模拟数据开始
      let res = {
        code: 0,
        msg: null,
        count: 24,
        data: [
        { 
      id:1,
      "date": "2024-04-01",  
      "category": "广告投放",  
      "description": "如何选择合适的广告投放平台？",  
      "solution": "根据目标受众、预算和广告类型选择适合的平台。",  
      "product": "广告平台X",  
      "interactionCount": 18,  
      "satisfaction": "92%"  
    },  
    {  
      id:2,
      "date": "2024-04-02",  
      "category": "广告创意",  
      "description": "如何制作吸引人的广告创意？",  
      "solution": "结合品牌特色，使用醒目的视觉元素和吸引人的文案。",  
      "product": "创意工具Y",  
      "interactionCount": 15,  
      "satisfaction": "88%"  
    },  
    {  
      id:3,
      "date": "2024-04-03",  
      "category": "广告效果分析",  
      "description": "如何评估广告投放的效果？",  
      "solution": "使用数据分析工具，分析点击率、转化率等指标。",  
      "product": "分析系统Z",  
      "interactionCount": 22,  
      "satisfaction": "95%"  
    },  
    {  
      id:4,
      "date": "2024-04-04",  
      "category": "广告合作",  
      "description": "如何寻找合适的广告合作伙伴？",  
      "solution": "参加行业展会、加入广告联盟或利用社交媒体平台。",  
      "product": "合作伙伴管理工具A",  
      "interactionCount": 17,  
      "satisfaction": "89%"  
    },  
    {  
      id:5,
      "date": "2024-04-05",  
      "category": "广告预算规划",  
      "description": "如何制定有效的广告预算？",  
      "solution": "根据业务目标、市场竞争和预算限制进行合理规划。",  
      "product": "预算规划软件B",  
      "interactionCount": 13,  
      "satisfaction": "90%"  
    },  
    {  
      id:6,
      "date": "2024-04-06",  
      "category": "广告法规",  
      "description": "广告投放需要遵守哪些法规？",  
      "solution": "了解并遵守广告法、消费者权益保护法等相关法律法规。",  
      "product": "法律咨询平台C",  
      "interactionCount": 19,  
      "satisfaction": "87%"  
    },  
    {  
      id:7,
      "date": "2024-04-07",  
      "category": "广告素材制作",  
      "description": "如何制作高质量的广告素材？",  
      "solution": "使用专业设计软件，注重色彩搭配和排版设计。",  
      "product": "设计工具D",  
      "interactionCount": 20,  
      "satisfaction": "93%"  
    },  
    {  
      id:10,
      "date": "2024-04-08",  
      "category": "广告定位",  
      "description": "如何确定广告的目标受众？",  
      "solution": "通过市场调研、用户画像等方式确定目标受众。",  
      "product": "市场调研工具E",  
      "interactionCount": 16,  
      "satisfaction": "91%"  
    },  
    {  
      id:8,
      "date": "2024-04-09",  
      "category": "广告效果优化",  
      "description": "如何提升广告点击率和转化率？",  
      "solution": "优化广告文案、调整投放时间、测试不同版本等。",  
      "product": "广告优化平台F",  
      "interactionCount": 21,  
      "satisfaction": "86%"  
    },  
    {  
      id:9,
      "date": "2024-04-10",  
      "category": "广告监测",  
      "description": "如何监测广告的投放效果？",  
      "solution": "使用广告监测工具，实时跟踪广告展现、点击和转化数据。",  
      "product": "广告监测工具G",  
      "interactionCount": 14,  
      "satisfaction": "94%"  
    }  
        ]
      }
      this.loading = false
      this.lists = res.data
      this.paging.currentPage = this.listInline.page
      this.paging.pageSize = this.listInline.limit
      this.paging.total = res.count
      // 测试环境  模拟数据结束  
      // 正式环境环境 调用接口
       knowledgeData(recordContent)
          .then(res => {
            this.loading = false
            if (res.success == false) {
              this.$message({
                type: 'info',
                message: res.msg
              })
            } else {
              this.lists = res.data
              // 分页赋值
              this.paging.currentPage = this.listInline.page
              this.paging.pageSize = this.listInline.limit
              this.paging.total = res.count
            }
          })
          .catch(err => {
            this.loading = false
            this.$message.error('知识库列表加载失败，请稍后再试！')
          })
    },
    // 分页插件事件
    callFather(parm) {
      this.listInline.page = parm.currentPage
      this.listInline.limit = parm.pageSize
      this.getdata(this.listInline)
    },
    // 搜索事件
    search() {
      this.getdata(this.listInline)
    },
    //添加、编辑
    knowledgeEdit: function (index, row) {
      this.recordVisible = true
      this.title = '查看'
      this.knowledge.date = row.date
      this.knowledge.category = row.category
      this.knowledge.description = row.description
      this.knowledge.solution = row.solution
      this.knowledge.response = row.response
      this.knowledge.product = row.product
      this.knowledge.interactionCount = row.interactionCount
      this.knowledge.satisfaction = row.satisfaction
    },
    // 删除知识库列表
    deleteknowledge(index, row) {
      this.$confirm(`确定要删除知识库吗?`, '删除知识库', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          knowledgeDelete(row.id)
            .then(res => {
              if (res.success) {
                this.$message({
                  type: 'success',
                  message: '知识库已删除!'
                })
                this.getdata(this.listInline)
              } else {
                this.$message({
                  type: 'info',
                  message: res.msg
                })
              }
            })
            .catch(err => {
              this.loading = false
              this.$message.error('知识库删除失败，请稍后再试！')
            })
        })
        .catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除知识库'
          })
        })
    },
    // 关闭弹框
    closeDialog() {
      this.recordVisible = false
    }
  }
}
</script>
<!-- 知识库添加 -->
<template>
  <div>
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>知识库添加</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="knowledge-base-add">  
    <el-form  :label-position='left' :model="form" ref="form" :rules="rules" label-width="100px">  
      <el-form-item  label="日期">  
        <el-date-picker  
          v-model="form.date"  
          type="date"  
          placeholder="选择日期"  
          :picker-options="pickerOptions"  
        ></el-date-picker>  
      </el-form-item>  
      <el-form-item label="问题分类">  
        <el-select v-model="form.category" placeholder="请选择问题分类">  
          <el-option  
            v-for="item in categories"  
            :key="item.value"  
            :label="item.label"  
            :value="item.value">  
          </el-option>  
        </el-select>  
      </el-form-item>  
      <el-form-item label="问题描述">  
        <el-input type="textarea" :rows="10" v-model="form.description"></el-input>  
      </el-form-item>  
      <el-form-item label="解决方案">  
        <el-input type="textarea" :rows="10" v-model="form.solution"></el-input>  
      </el-form-item>  
      <el-form-item label="关联产品">  
        <el-select v-model="form.product" placeholder="请选择关联产品">  
          <el-option  
            v-for="item in products"  
            :key="item.value"  
            :label="item.label"  
            :value="item.value">  
          </el-option>  
        </el-select>  
      </el-form-item>  
      <el-form-item>  
        <el-button type="primary" @click="submitForm('form')">提交</el-button>  
        <el-button @click="resetForm('form')">重置</el-button>  
      </el-form-item>  
    </el-form>  
  </div>  
  </div>
</template>
<script>
export default {
  data() {
    return {
      form: {  
        date: '',  
        category: '',  
        description: '',  
        solution: '',  
        product: ''  
      },  
      categories: [  
        { value: '广告投放', label: '广告投放' },  
        { value: '广告创意', label: '广告创意' },  
        { value: '广告效果分析', label: '广告效果分析' },  
      ],  
      products: [  
        { value: '广告平台A', label: '广告平台A' },  
        { value: '创意工具B', label: '创意工具B' },  
        { value: '分析系统C', label: '分析系统C' },  
      ],  
      pickerOptions: {  
        disabledDate(time) {  
          const endDate = new Date();  
          return time.getTime() > endDate.getTime();  
        }  
      } , 
      rules: {  
        date: [  
          { required: true, message: '请选择日期', trigger: 'change' },  
        ],  
        category: [  
          { required: true, message: '请选择问题分类', trigger: 'change' },  
        ],  
        description: [  
          { required: true, message: '请输入问题描述', trigger: 'blur' },  
        ],  
        solution: [  
          { required: true, message: '请输入解决方案', trigger: 'blur' },  
        ],  
        product: [  
          { required: true, message: '请选择关联产品', trigger: 'change' },  
        ],  
      }  
    };  
  },  
  created() {
  },
  methods: {
    submitForm(formName) {  
      this.$refs[formName].validate((valid) => {  
        if (valid) {  
          this.$message({
                  type: 'success',
                  message: '提交成功!'
                }) 
          //进行表单数据的提交处理，
          this.submitToServer(this.form); 
        } else {  
          this.$message({
                  type: 'info',
                  message: res.msg
                }) 
          return false;  
        }  
      });  
    },  
    resetForm(formName) {  
      this.$refs[formName].resetFields();  
    }, 
    submitToServer(formData) {  
      axios.post('/api/your-endpoint', formData)  
        .then(response => {  
          // 请求成功  
          if (response.status === 200) {   
            const { success, message } = response.data;  
            if (success) {  
              // 提交成功
              this.$message({  
                message: '表单提交成功',  
                type: 'success'  
              });  
              this.resetForm('form');  
            } else {  
              this.$message.error(message);  
            }  
          } else {  
            this.$message.error('服务器响应错误');  
          }  
        })  
        .catch(error => {  
          // 请求失败
          if (error.response) {   
            this.$message.error('请求失败: ' + error.response.status);  
          } else if (error.request) {   
            this.$message.error('请求已发送，但未收到响应');  
          } else {  
            this.$message.error('请求出错');  
          }  
          console.error(error);  
        });  
    }  
  }
}
</script>
<style scoped>
.knowledge-base-add {  
  display: flex;  
  flex-direction: column;  
  align-items: center;  
  justify-content: center;  
  padding: 20px;  
  max-width: 800px;  
  margin: 0 auto;  
  background-color: #fff;  
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);  
  border-radius: 4px;  
}   
</style>
